package cn.dduan.fool.design.pattern.behavior.template;

/**
 * 模版方法模式
 * <p>
 * 原理：
 * 1、基于继承实现的，在抽象父类中声明一个模板方法，并在模板方法中定义算法的执行步骤（即算法骨架）
 * <p>
 * 优点：
 * 1、符合"开闭原则”，也能够实现代码复用，将不变的行为转移到父类，去除子类中的重复代码
 * <p>
 * 缺点：
 * 1、不同的实现都需要定义一个子类，导致类的个数的增加使得系统更加庞大，设计更加抽象
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
public class TemplateMethodPattern {
    public static void main(String[] args) {
        Student student = new Student();
        student.prepareGotoSchool();
        System.out.println();

        Teacher teacher = new Teacher();
        teacher.prepareGotoSchool();
    }
}

/**
 * 抽象类：定义整个流程骨架
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
abstract class AbstractPerson {
    // 模板方法，使用final修改，防止子类改变算法的实现步骤
    public final void prepareGotoSchool() {
        dressUp();
        eatBreakfast();
        takeThings();
    }

    // 以下是不同子类根据自身特性完成的具体步骤
    protected abstract void dressUp();

    protected abstract void eatBreakfast();

    protected abstract void takeThings();
}

/**
 * 具体实现
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class Student extends AbstractPerson {
    public Student() {
        System.out.println("学生");
    }

    @Override
    protected void dressUp() {
        System.out.println("穿校服");
    }

    @Override
    protected void eatBreakfast() {
        System.out.println("吃妈妈做好的早饭");
    }

    @Override
    protected void takeThings() {
        System.out.println("背书包，带上家庭作业和红领巾");
    }
}

/**
 * 具体实现
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class Teacher extends AbstractPerson {
    public Teacher() {
        System.out.println("教师");
    }

    @Override
    protected void dressUp() {
        System.out.println("穿工作服");
    }

    @Override
    protected void eatBreakfast() {
        System.out.println("做早饭，照顾孩子吃早饭");
    }

    @Override
    protected void takeThings() {
        System.out.println("带上昨晚准备的考卷");
    }
}